#include<functional>
#include<cassert>
#include<pthread.h>


class thread{
public:
    typedef std::function<void*(void*)> func_t;
    struct context
    {
        context(thread* _this, void* arg)
        : _this(_this),_arg(arg)
        {}
        thread* _this;
        void* _arg;
    };
    

    static void* start_routine(void* arg){
        context* ctx = static_cast<context*>(arg);
        void* ret =  ctx->_this->_func(ctx->_arg);
        delete ctx;
        return ret;
    }

    thread(func_t func,void* arg = nullptr)
    :_func(func),_arg(arg)
    {   
        context* ctx = new context(this,_arg);
        int n = pthread_create(&_tid,nullptr,start_routine,ctx);
        assert(n == 0);
        (void)n;
    }

    void join(){
        int n = pthread_join(_tid,nullptr);
        assert( n == 0 );
        (void ) n;
    }
    ~thread(){
    }

private:
    pthread_t _tid;
    func_t _func;
    void* _arg;
};
